package cn.csc.module.order.dal.mysql.item;

import cn.csc.framework.common.pojo.PageResult;
import cn.csc.framework.mybatis.core.mapper.BaseMapperX;
import cn.csc.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.csc.module.order.controller.admin.item.vo.*;
import cn.csc.module.order.controller.admin.order.vo.OrderReqVO;
import cn.csc.module.order.controller.app.order.vo.AppOrderItemCreateReqVO;
import cn.csc.module.order.controller.app.vo.OrderItemReqVO;
import cn.csc.module.order.dal.dataobject.item.OrderItemDO;
import cn.csc.module.order.enums.OrderStatus;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.math.BigInteger;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 订单项 Mapper
 *
 * @author liuchuang
 */
@Mapper
public interface OrderItemMapper extends BaseMapperX<OrderItemDO> {

    default PageResult<OrderItemDO> selectPage(OrderItemPageReqVO reqVO) {
        return selectPage(reqVO, new LambdaQueryWrapperX<OrderItemDO>()
                .eqIfPresent(OrderItemDO::getShopId, reqVO.getShopId())
                .eqIfPresent(OrderItemDO::getOrderId, reqVO.getOrderId())
                .eqIfPresent(OrderItemDO::getCategoryId, reqVO.getCategoryId())
                .eqIfPresent(OrderItemDO::getSpuId, reqVO.getSpuId())
                .eqIfPresent(OrderItemDO::getSkuId, reqVO.getSkuId())
                .eqIfPresent(OrderItemDO::getUserId, reqVO.getUserId())
                .eqIfPresent(OrderItemDO::getCount, reqVO.getCount())
                .likeIfPresent(OrderItemDO::getSpuName, reqVO.getSpuName())
                .likeIfPresent(OrderItemDO::getSkuName, reqVO.getSkuName())
                .eqIfPresent(OrderItemDO::getPic, reqVO.getPic())
                .eqIfPresent(OrderItemDO::getDeliveryType, reqVO.getDeliveryType())
                .betweenIfPresent(OrderItemDO::getShopCartTime, reqVO.getShopCartTime())
                .eqIfPresent(OrderItemDO::getPrice, reqVO.getPrice())
                .eqIfPresent(OrderItemDO::getSpuTotalAmount, reqVO.getSpuTotalAmount())
                .betweenIfPresent(OrderItemDO::getCreateTime, reqVO.getCreateTime())
                .orderByDesc(OrderItemDO::getId));
    }

    default List<OrderItemDO> selectList(OrderItemExportReqVO reqVO) {
        return selectList(new LambdaQueryWrapperX<OrderItemDO>()
                .eqIfPresent(OrderItemDO::getShopId, reqVO.getShopId())
                .eqIfPresent(OrderItemDO::getOrderId, reqVO.getOrderId())
                .eqIfPresent(OrderItemDO::getCategoryId, reqVO.getCategoryId())
                .eqIfPresent(OrderItemDO::getSpuId, reqVO.getSpuId())
                .eqIfPresent(OrderItemDO::getSkuId, reqVO.getSkuId())
                .eqIfPresent(OrderItemDO::getUserId, reqVO.getUserId())
                .eqIfPresent(OrderItemDO::getCount, reqVO.getCount())
                .likeIfPresent(OrderItemDO::getSpuName, reqVO.getSpuName())
                .likeIfPresent(OrderItemDO::getSkuName, reqVO.getSkuName())
                .eqIfPresent(OrderItemDO::getPic, reqVO.getPic())
                .eqIfPresent(OrderItemDO::getDeliveryType, reqVO.getDeliveryType())
                .betweenIfPresent(OrderItemDO::getShopCartTime, reqVO.getShopCartTime())
                .eqIfPresent(OrderItemDO::getPrice, reqVO.getPrice())
                .eqIfPresent(OrderItemDO::getSpuTotalAmount, reqVO.getSpuTotalAmount())
                .betweenIfPresent(OrderItemDO::getCreateTime, reqVO.getCreateTime())
                .eqIfPresent(OrderItemDO::getPayType, reqVO.getPayType())
                .orderByDesc(OrderItemDO::getId));
    }
    /**
     * 查询订单状态
     *
     * @param userId 当前登录人id
     * @return 订单状态列表
     */
     List<BigInteger> getItemByUserId(@Param("userId") BigInteger userId, @Param("orderId") BigInteger orderId);

    default List<OrderItemDO> getItemByUserIdAndShopId(BigInteger userId,BigInteger shopId) {
        return selectList(new LambdaQueryWrapperX<OrderItemDO>()
                .eqIfPresent(OrderItemDO::getShopId, shopId)
                .eqIfPresent(OrderItemDO::getUserId, userId)
                .eqIfPresent(OrderItemDO::getDeleted, "0")
                .orderByDesc(OrderItemDO::getShopCartTime));
    }

    default List<OrderItemDO> getByOrderIdAndShopId(BigInteger orderId,BigInteger shopId) {
        return selectList(new LambdaQueryWrapperX<OrderItemDO>()
                .eqIfPresent(OrderItemDO::getShopId, shopId)
                .eqIfPresent(OrderItemDO::getOrderId, orderId)
                .eqIfPresent(OrderItemDO::getDeleted, "0")
                .orderByDesc(OrderItemDO::getShopCartTime));
    }

    /**
     * 获得购物车订单项列表是否为空
     *
     * @param reqVO
     * @return 订单项列表
     */
    default OrderItemDO getItemOne(OrderItemReqVO reqVO){
        return selectOne(new LambdaQueryWrapperX<OrderItemDO>()
                .eqIfPresent(OrderItemDO::getShopId, reqVO.getShopId())
                .eqIfPresent(OrderItemDO::getSpuId, reqVO.getSpuId())
                .eqIfPresent(OrderItemDO::getSkuId, reqVO.getSkuId())
                .eqIfPresent(OrderItemDO::getUserId, reqVO.getUserId())
                .apply(" shop_cart_time is not null"));
    }


    default Integer updateOrderState(List<BigInteger> orderIds, Integer orderStatus){
        return update(null, new LambdaUpdateWrapper<OrderItemDO>()
                .set(OrderItemDO::getOrderStatus, orderStatus)
                .set(OrderItemDO::getFinallyTime, LocalDateTime.now())
                .in(OrderItemDO::getOrderId, orderIds));
    }

    /**
     * 查询订单有多少个商家id
     * @param orderId
     * @return
     */
    List<BigInteger> getShopIdByOrderId(BigInteger orderId);

    default List<OrderItemDO> getItemByUserIdAndShopIdAndOrderId(BigInteger userId, BigInteger shopId,BigInteger orderId) {
        return selectList(new LambdaQueryWrapperX<OrderItemDO>()
                .eqIfPresent(OrderItemDO::getUserId, userId)
                .eqIfPresent(OrderItemDO::getShopId, shopId)
                .eqIfPresent(OrderItemDO::getOrderId, orderId)
                .eq(OrderItemDO::getDeleted, 0)
                .orderByDesc(OrderItemDO::getCreateTime));
    }

    default List<OrderItemDO> selectList(OrderReqVO reqVO) {
        return selectList(new LambdaQueryWrapperX<OrderItemDO>()
                .eqIfPresent(OrderItemDO::getOrderStatus, reqVO.getOrderStatus())
                .lt(OrderItemDO::getDeliveryTime, reqVO.getDeliveryTime()));
    }
    /**
     * 分页查询订单信息，包含订单子项
     * @param reqVO 查询参数
     * @return
     */
    Page<OrderWithItemPageRespVO> selectOrderItemsPage(@Param("req") OrderWithItemPageReqVO reqVO, IPage<OrderWithItemPageRespVO> page);

    default List<OrderItemDO> selectList(OrderItemReqVO reqVO) {
        return selectList(new LambdaQueryWrapperX<OrderItemDO>()
                .eqIfPresent(OrderItemDO::getOrderId, reqVO.getOrderId())
                .eqIfPresent(OrderItemDO::getShopId, reqVO.getShopId())
                .eq(OrderItemDO::getDeleted, 0));
    }
    default Integer updateByToPaySuccess(List<BigInteger> orderIds){
        //根据支付订单号，查询订单的id，修改子项的支付状态;
        return update(null,new LambdaUpdateWrapper<OrderItemDO>()
                .set(OrderItemDO::getOrderStatus, OrderStatus.PADYED.value())
                .set(OrderItemDO::getPayTime, LocalDateTime.now())
                .set(OrderItemDO::getUpdateTime, LocalDateTime.now())
                .in(OrderItemDO::getOrderId, orderIds));
    }

    List<OrderItemBaseVO> getExportList(OrderWithItemPageReqVO pageVO);

    /**
     * 物理删除
     * @param orderId 订单ID
     * @return
     */
    Integer deleteByOrderId(@Param("orderId") BigInteger orderId);

    Integer updateAppUserIdBatch(List<OrderItemDO> list);

    default List<OrderItemDO> selectListByOrderIds(List<BigInteger> orderIds) {
        return selectList(new LambdaQueryWrapperX<OrderItemDO>()
                .inIfPresent(OrderItemDO::getOrderId,orderIds)
                .orderByDesc(OrderItemDO::getPayTime));
    }
}
